package com.dq;

import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import java.util.Map;

/**
 * @ClassName SpringApplication
 * @Description 启动run类
 * @Author DuX1aoQiang
 * @Date 2023/5/18 15:21
 * @Version 1.0
 */
public class DuSpringApplication {

    public static void run(Class<?> configClazz, String... args) {

        //创建Spring容器
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(configClazz);
        applicationContext.refresh();

        /**
         * first ： 启动tomcat | jetty  1. 配置AutoConfig  2. 加入Conditional注解  3. 利用maven依赖传递 实现依赖分离
         * second ： 利用getWebServer 返回的bean直接策略启动服务
         */
        WebServer webServer = getWebServer(applicationContext);
        webServer.start();
    }

    /**
     *
     * first ： jetty|tomcat动态切换启动  利用 .xml + .yaml 配置
     * second ： 利用AutoConfiguration 自动装配Bean然后返回这个Bean对象
     * @param applicationContext
     * @return
     */
    private static WebServer getWebServer(AnnotationConfigWebApplicationContext applicationContext) {
        Map<String, WebServer> webServers = applicationContext.getBeansOfType(WebServer.class);
        if (webServers.isEmpty()) {
            throw new NullPointerException();
        }
        if (webServers.size() > 1) {
            throw new IllegalStateException();
        }
        return webServers.values().stream().findFirst().get();
    }

    //内敛启动Tomcat
    private static void startTomcat(WebApplicationContext applicationContext) {
        Tomcat tomcat = new Tomcat();

        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");

        Connector connector = new Connector();
        connector.setPort(8081);

        StandardEngine engine = new StandardEngine();
        engine.setDefaultHost("localhost");

        Host host = new StandardHost();
        host.setName("localhost");

        String contextPath = "";
        StandardContext context = new StandardContext();
        context.setPath(contextPath);
        context.addLifecycleListener(new Tomcat.FixContextListener());

        host.addChild(context);
        engine.addChild(host);

        service.setContainer(engine);
        service.addConnector(connector);

        //利用DispatcherServlet 处理curl请求
        /*  源码传入模板参数  applicationContext 此容器装配所有
            public DispatcherServlet(WebApplicationContext webApplicationContext) {
                super(webApplicationContext);
                this.setDispatchOptionsRequest(true);
            }
         */
        tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*", "dispatcher");

        try {
            tomcat.start();
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        }
    }

}
